/*
 * COPYRIGHT. ShenZhen JiMi Technology Co., Ltd. 2017.
 * ALL RIGHTS RESERVED.
 *
 * No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
 * on any form or by any means, electronic, mechanical, photocopying, recording, 
 * or otherwise, without the prior written permission of ShenZhen JiMi Network Technology Co., Ltd.
 *
 * Amendment History:
 * 
 * Date                   By              Description
 * -------------------    -----------     -------------------------------------------
 * 2017年4月10日    li.shangzhi         Create the class
 * http://www.jimilab.com/
 */

package com.jimi.framework.interceptor.loginsecurity;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.jimi.exception.ErrorCode;
import com.jimi.framework.utils.RequestUtil;
import com.jimi.framework.utils.ResultModel;
import com.jimi.framework.utils.SessionUtil;
import com.jimi.utils.EncodeUtils;

/**
 * @FileName LoginSecurityContract.java
 * @Description: 登录校验拦截器
 *
 * @Date 2017年4月10日 下午8:29:28
 * @author li.shangzhi
 * @version 1.0
 */
@Aspect
@Component
// @Order(1)
@Configuration
public class LoginSecurityContract {
	protected final Logger logger = LoggerFactory.getLogger(LoginSecurityContract.class);

	protected static final String LOGIN_URL = "http://www.baidu.com";

	@Around("within(@org.springframework.web.bind.annotation.RestController *) && @annotation(loginSecurity)")
	public Object validIdentityAndSecure(final ProceedingJoinPoint pjp, LoginSecurity loginSecurity) throws Throwable {
		Object[] args = pjp.getArgs();
		// 筛选出HttpServletRequest
		HttpServletRequest request = null;
		for (int i = 0; i < args.length; i++) {
			if (args[i] instanceof HttpServletRequest) {
				request = (HttpServletRequest) args[i];
				break;
			}
		}
		if (null == request) {
			throw new Exception("没有设置HttpServletRequest参数");
		}
		Class<? extends Object> invokeClass = pjp.getTarget().getClass();
		String signatureName = pjp.getSignature().getName();
		Class<? extends Object> returnType = null; // 返回类型
		Method methods[] = invokeClass.getMethods();// 获取方法名
		Annotation[] annotations = null; // 获取注解
		for (Method method : methods) {
			if (method.getName().equals(signatureName)) {
				returnType = method.getReturnType();
				annotations = method.getAnnotations();
				break;
			}
		}

		String returnMsg = SessionUtil.getLoginaccount(request);
		if (null == returnMsg) {
			return new ResponseEntity(new ResultModel(ErrorCode.TOKEN_ERROR), HttpStatus.OK);
		} else if ("fail".equals(returnMsg)) {
			return new ResponseEntity(new ResultModel(ErrorCode.TOKEN_ERROR), HttpStatus.OK);
		}

		return pjp.proceed();
	}

	private Object getReturnType(Class<? extends Object> returnType, Annotation[] annotations, LoginSecurity ssi, HttpServletRequest request)
			throws Exception {
		if (returnType.equals(String.class)) {
			boolean hasResponseBody = false;
			for (int i = 0; i < annotations.length; i++) {
				if (annotations[i].annotationType().equals(ResponseBody.class)) {
					hasResponseBody = true;
					break;
				}
			}
			if (hasResponseBody) {
				return ssi.json();
			} else {
				return getLoginUrl(request, ssi);
			}
		} else if (returnType.equals(ModelAndView.class)) {
			return new ModelAndView(getLoginUrl(request, ssi));
		} else {
			logger.error("视图处理异常");
			throw new Exception("视图处理异常");
		}
	}

	/**
	 * @Title: getLoginUrl
	 * @Description: 得到登录界面Url
	 * @param request
	 * @param ssi
	 * @return
	 * @author li.shangzhi
	 * @date 2017年4月10日 下午8:32:09
	 */
	private String getLoginUrl(HttpServletRequest request, LoginSecurity ssi) {
		String loginUrl = "redirect:" + LOGIN_URL;
		String redirectUrl = ssi.redirect();
		String originUrl = RequestUtil.getUrl(request);
		if (redirectUrl.equals(LoginSecurity.BACK)) {
			if (originUrl != null) {
				loginUrl = loginUrl + "?redirectURL=" + originUrl;
			}
		} else if (redirectUrl.equals(LoginSecurity.DEFAULT)) {
			return loginUrl;
		} else {
			loginUrl = loginUrl + "?redirectURL=" + RequestUtil.urlEncode(redirectUrl);
		}

		if (originUrl != null) {
			logger.warn("用户IP:{}未验证身份,来源地址是:{}", RequestUtil.getIpAddr(request), EncodeUtils.urlDecode(originUrl));
		} else {
			logger.warn("用户IP:{}未验证身份", RequestUtil.getIpAddr(request));
		}
		return loginUrl;
	}

}